package cn.gx.kevin.common.utils;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;

import java.util.Properties;

/***
 *@description : 动态任务管理器
 *@author : kevin.huang
 *@date : 2020/1/3 20:14
 @modified by
 ***/
public class QuartzManager {

    private static StdSchedulerFactory schedulerFactory = null;
    private final static Logger logger = org.slf4j.LoggerFactory.getLogger(QuartzManager.class);

    static {
        String count = "6";
        Object tmp = SysConfigParams.getConfig("quartzThreadCount");
        if(tmp != null){
            count = String.valueOf(tmp);
        }
        Properties props = new Properties();
        props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,"org.quartz.simpl.SimpleThreadPool");
        props.put("org.quartz.threadPool.threadCount", count);
        try {
            schedulerFactory = new StdSchedulerFactory();
            schedulerFactory.initialize(props);
        }catch (Exception x) {
            logger.error("", x);
        }
    }

    /******
     * 清理删除所有job
     * *******/
    public static  boolean clearAllJob(){
        try{
            Scheduler sched = schedulerFactory.getScheduler();
            sched.clear();
        }catch (Exception x){
            logger.error("",x);
            return false;
        }
        return true;
    }


    /**
     *  添加一个定时任务
     *
     * @param jobName 任务名
     * @param jobGroupName  任务组名
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名
     * @param jobClass  任务
     * @param cron   时间设置，参考quartz说明文档
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static boolean addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class jobClass, String cron) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();

            // 任务名，任务组，任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

            // 触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);

            // 启动
            if (!sched.isShutdown()) {
                sched.start();
            }
            return true;
        } catch (Exception e) {
            logger.error("",e);
            return false;
        }
    }

    /**
     *  修改一个任务的触发时间
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名
     * @param cron   时间设置，参考quartz说明文档
     */
    public static boolean modifyJobTime(String jobName,String jobGroupName, String triggerName, String triggerGroupName, String cron) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {
                return false;
            }

            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                /** 方式一 ：调用 rescheduleJob 开始 */
                // 触发器
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 ：修改一个任务的触发时间
                sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 ：调用 rescheduleJob 结束 */

                /** 方式二：先删除，然后在创建一个新的Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
                //Class<? extends Job> jobClass = jobDetail.getJobClass();
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
                /** 方式二 ：先删除，然后在创建一个新的Job */
            }
            return true;
        } catch (Exception e) {
            logger.error("",e);
            return  false;
        }
    }


    public static boolean checkExistsJob(String jobName, String jobGroupName){
        boolean isIn = true;
        try {
            JobKey key = JobKey.jobKey(jobName, jobGroupName);
            Scheduler sched = schedulerFactory.getScheduler();
            isIn = sched.checkExists(key);
        } catch (Exception e) {
            logger.error("",e);
            isIn = false;
        }
        return  isIn;
    }


    /**
     *  移除一个任务
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    public static boolean removeJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            sched.pauseTrigger(triggerKey);// 停止触发器
            sched.unscheduleJob(triggerKey);// 移除触发器
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
            logger.info("移除{}定时任务成功!",jobName);
            return true;
        } catch (Exception e) {
            logger.error("",e);
            return false;
        }
    }

    /**
     * 启动所有定时任务
     */
    public static boolean startJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            if(!sched.isStarted()){
                sched.start();
            }
            return  true;
        } catch (Exception e) {
            logger.error("",e);
           return false;
        }
    }

    /**
     * 关闭所有定时任务
     */
    public static boolean shutdownJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            if (!sched.isShutdown()) {
                sched.shutdown();
            }
            return true;
        } catch (Exception e) {
            logger.error("",e);
            return false;
        }
    }
}
